package me.qi.kancha.generator;

import me.qi.kancha.dto.core.UserDTO;
import me.qi.kancha.dto.enums.base.BaseEnum;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author sun
 * @date 2022/6/26 13:45
 * @modified By：
 */
public class ResultMapGenerator {
    private static Pattern humpPattern = Pattern.compile("[A-Z]");
    private static Map<String, String> TYPE_MAP = new HashMap<>();
    static {
        TYPE_MAP.put("java.lang.string", "VARCHAR");
        TYPE_MAP.put("java.lang.boolean", "BIT");
        TYPE_MAP.put("java.lang.short", "SMALLINT");
        TYPE_MAP.put("java.lang.integer", "INTEGER");
        TYPE_MAP.put("java.lang.long", "BIGINT");
        TYPE_MAP.put("java.lang.double", "DOUBLE");
        TYPE_MAP.put("java.lang.float", "REAL");
        TYPE_MAP.put("java.util.date", "TIMESTAMP");//TIMESTAMP,DATETIME
        TYPE_MAP.put("java.math.bigdecimal", "DECIMAL");

        TYPE_MAP.put("byte", "TINYINT");
        TYPE_MAP.put("int", "INTEGER");
        TYPE_MAP.put("timestamp", "TIMESTAMP");
        TYPE_MAP.put("time", "TIME");
    }

    /**
     * 获取ResultMap
     * @param clazz 实体类的Class
     * @return String
     */
    public static String buildResultMap(Class<?> clazz){
        Object obj = null;
        try{
            obj = clazz.newInstance();
        }catch (Exception e){
            return "#Exception.反射生成实体异常#";
        }

        String clazzName = clazz.getSimpleName();
        String resultMapId = Character.toLowerCase(clazzName.charAt(0))+clazzName.substring(1)+"Map";
        String pkgName = clazz.getName();

        StringBuilder resultMap = new StringBuilder();
        resultMap.append("<resultMap id=\"");
        resultMap.append(resultMapId);
        resultMap.append("\" type=\"");
        resultMap.append(pkgName);
        resultMap.append("\">\n");

                Field[] fields = clazz.getDeclaredFields();
        for(Field f : fields){
            String property = f.getName();

            if("serialVersionUID".equals(property)){
                continue;//忽略掉这个属性
            }
            resultMap.append("    <result property=\"");
            resultMap.append(property);
            resultMap.append("\" column=\"");
            resultMap.append(property2Column(property));
            resultMap.append("\" jdbcType=\"");
            resultMap.append(javaType2jdbcType(f));
            resultMap.append("\" />\n");
        }
        resultMap.append("</resultMap>");
        return resultMap.toString();
    }

    private static String property2Column(String property){
        Matcher matcher = humpPattern.matcher(property);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()){
            matcher.appendReplacement(sb, "_"+matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    private static String javaType2jdbcType(Field f){
        String javaType = f.getType().getName();
        javaType = javaType.toLowerCase();
        String jdbcType = TYPE_MAP.get(javaType);
        if (jdbcType == null) {
            if (BaseEnum.class.isAssignableFrom(f.getType())) {
                return "INTEGER";
            }
            return "UNKNOWN";
        } else {
            return jdbcType;
        }
    }

    public static void main(String[] args) {
        System.out.println(buildResultMap(UserDTO.class));
    }
}